﻿using System.ComponentModel;
using Framework.Core.Notification;
using Rhino.Mocks;
using Xunit;

namespace Framework.Tests.Core.Notification
{
    extern alias castlecore;

    public class Deal : IAutoNotifyPropertyChanged
    {
        public virtual int Id { get; set; }
        public virtual string DealType { get; set; }
        public virtual string Underlying { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

    public class NotityChangedTest
    {
        public NotityChangedTest()
        {
            var mockRepository = new MockRepository();
            mockRepository.Stub<castlecore::Castle.DynamicProxy.IInterceptor>();
        }

        [Fact]
        public void Should_notify_when_property_changed()
        {
            var deal = new Deal().AsObservable();
            string changedProperty = null;
            PropertyChangedEventHandler propertyChangedEventHandler = (o, s) => { changedProperty = s.PropertyName; };
            deal.PropertyChanged += propertyChangedEventHandler;

            deal.DealType = "pouet";

            Assert.Equal("DealType", changedProperty);

            changedProperty = null;

            deal.DealType = "toto";

            Assert.Equal("DealType", changedProperty);

            deal.PropertyChanged -= propertyChangedEventHandler;

            deal.Underlying = "toto";

            Assert.NotEqual("Underlying", changedProperty);
        }

        [Fact]
        public void Should_throw_notification_exception_if_instance_is_not_auto_inotifypropertychanged()
        {
            var deal = new BadDeal().AsObservable();

            Assert.Throws<NotificationException>(() => deal.DealType = "puoet");
        }

        public class BadDeal
        {
            public virtual int Id { get; set; }
            public virtual string DealType { get; set; }
        }
    }
}